import { defineStore } from 'pinia';
import { fabric } from '@/utils/fabricWrapper';
import { eventBus } from '@/utils/eventBus';
import { useSettingsStore } from './settings';

// 编辑模式类型
export type EditMode = 'select' | 'move' | 'edit' | 'draw';

// 工具类型
export type ToolType = 'select' | 'text' | 'shape' | 'image' | 'pen';

// 侧边栏标签类型
export type SidebarTabType = 'layers' | 'elements' | 'settings';

// 形状类型
export type ShapeType = 'rect' | 'circle' | 'ellipse' | 'line' | 'polygon' | 'path';

// 编辑器状态接口
interface EditorState {
  // 画布状态
  canvas: {
    width: number;
    height: number;
    zoom: number;
    pan: { x: number; y: number };
    showGrid: boolean;
    showRulers: boolean;
    backgroundColor: string;
    fabricCanvas: fabric.Canvas | null;
  };
  
  // 选择状态
  selection: {
    activeElementId: string | null;
    selectedElementIds: string[];
    isMultiSelect: boolean;
    activeObject: fabric.Object | null;
    activeObjects: fabric.Object[];
  };
  
  // 编辑模式
  editMode: EditMode;
  
  // 工具状态
  activeTool: ToolType;
  activeShapeType: ShapeType;
  
  // 界面状态
  ui: {
    sidebarOpen: boolean;
    activeSidebarTab: SidebarTabType;
    showToolbar: boolean;
    isMobileView: boolean;
    isLoading: boolean;
    showContextMenu: boolean;
    contextMenuPosition: { x: number; y: number };
  };
  
  // 项目状态
  project: {
    id: string | null;
    name: string;
    isDirty: boolean;
    lastSaved: Date | null;
  };
}

/**
 * 编辑器状态存储
 */
export const useEditorStore = defineStore('editor', {
  state: (): EditorState => ({
    // 画布状态
    canvas: {
      width: 800,
      height: 600,
      zoom: 1,
      pan: { x: 0, y: 0 },
      showGrid: false,
      showRulers: false,
      backgroundColor: '#ffffff',
      fabricCanvas: null
    },
    
    // 选择状态
    selection: {
      activeElementId: null,
      selectedElementIds: [],
      isMultiSelect: false,
      activeObject: null,
      activeObjects: []
    },
    
    // 编辑模式
    editMode: 'select',
    
    // 工具状态
    activeTool: 'select',
    activeShapeType: 'rect',
    
    // 界面状态
    ui: {
      sidebarOpen: true,
      activeSidebarTab: 'layers',
      showToolbar: true,
      isMobileView: false,
      isLoading: false,
      showContextMenu: false,
      contextMenuPosition: { x: 0, y: 0 }
    },
    
    // 项目状态
    project: {
      id: null,
      name: '未命名项目',
      isDirty: false,
      lastSaved: null
    }
  }),
  
  getters: {
    /**
     * 是否有选中的元素
     */
    hasSelection: (state) => state.selection.selectedElementIds.length > 0,
    
    /**
     * 是否有多个选中的元素
     */
    hasMultiSelection: (state) => state.selection.selectedElementIds.length > 1,
    
    /**
     * 获取当前缩放比例
     */
    currentZoom: (state) => state.canvas.zoom,
    
    /**
     * 是否处于移动模式
     */
    isMoveMode: (state) => state.editMode === 'move',
    
    /**
     * 是否处于编辑模式
     */
    isEditMode: (state) => state.editMode === 'edit',
    
    /**
     * 是否处于绘制模式
     */
    isDrawMode: (state) => state.editMode === 'draw',
    
    /**
     * 获取画布实例
     */
    getFabricCanvas: (state) => state.canvas.fabricCanvas,
    
    /**
     * 获取活动元素
     */
    getActiveObject: (state) => state.selection.activeObject,
    
    /**
     * 获取选中的元素
     */
    getSelectedObjects: (state) => state.selection.activeObjects,
    
    /**
     * 获取项目是否有未保存的更改
     */
    isProjectDirty: (state) => state.project.isDirty
  },
  
  actions: {
    /**
     * 初始化画布
     * @param canvas Fabric.js 画布实例
     */
    initCanvas(canvas: fabric.Canvas) {
      this.canvas.fabricCanvas = canvas;
      
      // 设置画布背景色
      canvas.setBackgroundColor(this.canvas.backgroundColor, canvas.renderAll.bind(canvas));
      
      // 监听画布事件
      this.setupCanvasEvents();
      
      // 发送画布初始化完成事件
      eventBus.emit('canvas:initialized', { canvas });
    },
    
    /**
     * 设置画布事件监听
     */
    setupCanvasEvents() {
      const canvas = this.canvas.fabricCanvas;
      if (!canvas) return;
      
      // 监听选择事件
      canvas.on('selection:created', this.handleSelectionCreated);
      canvas.on('selection:updated', this.handleSelectionUpdated);
      canvas.on('selection:cleared', this.handleSelectionCleared);
      
      // 监听对象修改事件
      canvas.on('object:modified', this.handleObjectModified);
      canvas.on('object:moving', this.handleObjectMoving);
      canvas.on('object:scaling', this.handleObjectScaling);
      canvas.on('object:rotating', this.handleObjectRotating);
      
      // 监听鼠标事件
      canvas.on('mouse:down', this.handleMouseDown);
      canvas.on('mouse:move', this.handleMouseMove);
      canvas.on('mouse:up', this.handleMouseUp);
      canvas.on('mouse:wheel', this.handleMouseWheel);
      
      // 监听键盘事件
      document.addEventListener('keydown', this.handleKeyDown);
      document.addEventListener('keyup', this.handleKeyUp);
    },
    
    /**
     * 处理选择创建事件
     */
    handleSelectionCreated(e: fabric.IEvent) {
      const activeObject = e.selected?.[0];
      if (!activeObject) return;
      
      // 更新选择状态
      this.selection.activeObject = activeObject;
      this.selection.activeObjects = e.selected || [];
      
      // 更新选中元素ID
      if (activeObject.id) {
        this.selection.activeElementId = activeObject.id as string;
        this.selection.selectedElementIds = this.selection.activeObjects
          .map(obj => obj.id as string)
          .filter(Boolean);
      }
      
      // 发送元素选中事件
      eventBus.emit('element:selected', { 
        element: activeObject,
        elementId: activeObject.id || 'unknown'
      });
    },
    
    /**
     * 处理选择更新事件
     */
    handleSelectionUpdated(e: fabric.IEvent) {
      this.handleSelectionCreated(e);
    },
    
    /**
     * 处理选择清除事件
     */
    handleSelectionCleared() {
      // 清除选择状态
      this.selection.activeObject = null;
      this.selection.activeObjects = [];
      this.selection.activeElementId = null;
      this.selection.selectedElementIds = [];
      
      // 发送元素取消选择事件
      eventBus.emit('element:deselected');
    },
    
    /**
     * 处理对象修改事件
     */
    handleObjectModified(e: fabric.IEvent) {
      if (!e.target) return;
      
      // 标记项目为已修改
      this.setProjectDirty(true);
      
      // 发送元素修改事件
      eventBus.emit('element:modified', {
        element: e.target,
        elementId: e.target.id || 'unknown'
      });
    },
    
    /**
     * 处理对象移动事件
     */
    handleObjectMoving(e: fabric.IEvent) {
      if (!e.target) return;
      
      // 处理网格吸附
      const settingsStore = useSettingsStore();
      if (settingsStore.snapToGrid) {
        this.snapObjectToGrid(e.target);
      }
      
      // 发送元素移动事件
      eventBus.emit('element:moving', {
        element: e.target,
        elementId: e.target.id || 'unknown'
      });
    },
    
    /**
     * 处理对象缩放事件
     */
    handleObjectScaling(e: fabric.IEvent) {
      if (!e.target) return;
      
      // 发送元素缩放事件
      eventBus.emit('element:scaling', {
        element: e.target,
        elementId: e.target.id || 'unknown'
      });
    },
    
    /**
     * 处理对象旋转事件
     */
    handleObjectRotating(e: fabric.IEvent) {
      if (!e.target) return;
      
      // 发送元素旋转事件
      eventBus.emit('element:rotating', {
        element: e.target,
        elementId: e.target.id || 'unknown'
      });
    },
    
    /**
     * 处理鼠标按下事件
     */
    handleMouseDown(opt: fabric.IEvent) {
      // 处理平移模式
      if (opt.e.altKey && this.canvas.fabricCanvas) {
        this.canvas.fabricCanvas.isDragging = true;
        this.canvas.fabricCanvas.selection = false;
        this.canvas.fabricCanvas.lastPosX = opt.e.clientX;
        this.canvas.fabricCanvas.lastPosY = opt.e.clientY;
      }
      
      // 处理右键菜单
      if (opt.e.button === 2) {
        this.showContextMenu(opt.e.clientX, opt.e.clientY);
        opt.e.preventDefault();
      }
    },
    
    /**
     * 处理鼠标移动事件
     */
    handleMouseMove(opt: fabric.IEvent) {
      const canvas = this.canvas.fabricCanvas;
      if (!canvas || !canvas.isDragging) return;
      
      // 处理画布平移
      const e = opt.e;
      const vpt = canvas.viewportTransform!;
      vpt[4] += e.clientX - canvas.lastPosX;
      vpt[5] += e.clientY - canvas.lastPosY;
      canvas.requestRenderAll();
      canvas.lastPosX = e.clientX;
      canvas.lastPosY = e.clientY;
      
      // 更新平移状态
      this.setPan(vpt[4], vpt[5]);
    },
    
    /**
     * 处理鼠标抬起事件
     */
    handleMouseUp() {
      const canvas = this.canvas.fabricCanvas;
      if (!canvas) return;
      
      // 结束画布平移
      canvas.isDragging = false;
      canvas.selection = true;
    },
    
    /**
     * 处理鼠标滚轮事件
     */
    handleMouseWheel(opt: fabric.IEvent) {
      const canvas = this.canvas.fabricCanvas;
      if (!canvas) return;
      
      // 处理画布缩放
      const delta = opt.e.deltaY;
      let zoom = canvas.getZoom();
      zoom *= 0.999 ** delta;
      
      if (zoom > 20) zoom = 20;
      if (zoom < 0.01) zoom = 0.01;
      
      canvas.zoomToPoint({ x: opt.e.offsetX, y: opt.e.offsetY }, zoom);
      
      // 更新缩放状态
      this.setZoom(zoom);
      
      opt.e.preventDefault();
      opt.e.stopPropagation();
    },
    
    /**
     * 处理键盘按下事件
     */
    handleKeyDown(e: KeyboardEvent) {
      const settingsStore = useSettingsStore();
      if (!settingsStore.enableShortcuts) return;
      
      // 处理快捷键
      if (e.ctrlKey || e.metaKey) {
        switch (e.key.toLowerCase()) {
          case 'z':
            if (e.shiftKey) {
              // Ctrl+Shift+Z: 重做
              eventBus.emit('history:redo');
            } else {
              // Ctrl+Z: 撤销
              eventBus.emit('history:undo');
            }
            e.preventDefault();
            break;
          case 'y':
            // Ctrl+Y: 重做
            eventBus.emit('history:redo');
            e.preventDefault();
            break;
          case 'c':
            // Ctrl+C: 复制
            this.copySelectedElements();
            e.preventDefault();
            break;
          case 'v':
            // Ctrl+V: 粘贴
            this.pasteElements();
            e.preventDefault();
            break;
          case 'x':
            // Ctrl+X: 剪切
            this.cutSelectedElements();
            e.preventDefault();
            break;
          case 'a':
            // Ctrl+A: 全选
            this.selectAllElements();
            e.preventDefault();
            break;
          case 's':
            // Ctrl+S: 保存
            this.saveProject();
            e.preventDefault();
            break;
        }
      } else {
        switch (e.key) {
          case 'Delete':
          case 'Backspace':
            // Delete: 删除选中元素
            this.deleteSelectedElements();
            break;
          case 'Escape':
            // Escape: 取消选择
            this.clearSelection();
            break;
        }
      }
    },
    
    /**
     * 处理键盘抬起事件
     */
    handleKeyUp(e: KeyboardEvent) {
      // 可以在这里处理一些键盘抬起的逻辑
    },
    
    /**
     * 将对象吸附到网格
     * @param object Fabric.js 对象
     */
    snapObjectToGrid(object: fabric.Object) {
      const settingsStore = useSettingsStore();
      const gridSize = settingsStore.gridSize;
      
      if (!object.left || !object.top) return;
      
      // 计算吸附位置
      const left = Math.round(object.left / gridSize) * gridSize;
      const top = Math.round(object.top / gridSize) * gridSize;
      
      // 设置对象位置
      object.set({
        left,
        top
      });
    },
    
    /**
     * 显示上下文菜单
     * @param x X坐标
     * @param y Y坐标
     */
    showContextMenu(x: number, y: number) {
      this.ui.showContextMenu = true;
      this.ui.contextMenuPosition = { x, y };
      
      // 添加点击外部关闭菜单的事件
      setTimeout(() => {
        const closeContextMenu = () => {
          this.hideContextMenu();
          document.removeEventListener('click', closeContextMenu);
        };
        document.addEventListener('click', closeContextMenu);
      }, 0);
    },
    
    /**
     * 隐藏上下文菜单
     */
    hideContextMenu() {
      this.ui.showContextMenu = false;
    },
    
    /**
     * 设置画布尺寸
     * @param width 宽度
     * @param height 高度
     */
    setCanvasSize(width: number, height: number) {
      this.canvas.width = width;
      this.canvas.height = height;
      
      // 更新Fabric.js画布尺寸
      if (this.canvas.fabricCanvas) {
        this.canvas.fabricCanvas.setDimensions({ width, height });
      }
      
      // 发送画布尺寸变更事件
      eventBus.emit('canvas:resized', { width, height });
    },
    
    /**
     * 设置缩放级别
     * @param zoom 缩放级别
     */
    setZoom(zoom: number) {
      this.canvas.zoom = Math.max(0.1, Math.min(20, zoom));
      
      // 发送画布缩放事件
      eventBus.emit('canvas:zoomed', { zoom: this.canvas.zoom });
    },
    
    /**
     * 设置平移位置
     * @param x X坐标
     * @param y Y坐标
     */
    setPan(x: number, y: number) {
      this.canvas.pan = { x, y };
      
      // 发送画布平移事件
      eventBus.emit('canvas:panned', { pan: this.canvas.pan });
    },
    
    /**
     * 切换网格显示
     */
    toggleGrid() {
      this.canvas.showGrid = !this.canvas.showGrid;
      
      // 发送网格显示变更事件
      eventBus.emit('canvas:grid-toggled', { showGrid: this.canvas.showGrid });
    },
    
    /**
     * 切换标尺显示
     */
    toggleRulers() {
      this.canvas.showRulers = !this.canvas.showRulers;
      
      // 发送标尺显示变更事件
      eventBus.emit('canvas:rulers-toggled', { showRulers: this.canvas.showRulers });
    },
    
    /**
     * 设置背景颜色
     * @param color 颜色值
     */
    setBackgroundColor(color: string) {
      this.canvas.backgroundColor = color;
      
      // 更新Fabric.js画布背景色
      if (this.canvas.fabricCanvas) {
        this.canvas.fabricCanvas.setBackgroundColor(color, this.canvas.fabricCanvas.renderAll.bind(this.canvas.fabricCanvas));
      }
      
      // 发送背景颜色变更事件
      eventBus.emit('canvas:background-changed', { backgroundColor: color });
    },
    
    /**
     * 选择元素
     * @param elementId 元素ID
     */
    selectElement(elementId: string) {
      if (this.selection.isMultiSelect) {
        if (!this.selection.selectedElementIds.includes(elementId)) {
          this.selection.selectedElementIds.push(elementId);
        }
      } else {
        this.selection.selectedElementIds = [elementId];
      }
      this.selection.activeElementId = elementId;
      
      // 发送元素选择事件
      eventBus.emit('element:selected', { elementId });
    },
    
    /**
     * 取消选择元素
     * @param elementId 元素ID
     */
    deselectElement(elementId: string) {
      this.selection.selectedElementIds = this.selection.selectedElementIds.filter(id => id !== elementId);
      if (this.selection.activeElementId === elementId) {
        this.selection.activeElementId = this.selection.selectedElementIds[0] || null;
      }
      
      // 发送元素取消选择事件
      eventBus.emit('element:deselected', { elementId });
    },
    
    /**
     * 清除所有选择
     */
    clearSelection() {
      // 清除Fabric.js画布选择
      if (this.canvas.fabricCanvas) {
        this.canvas.fabricCanvas.discardActiveObject();
        this.canvas.fabricCanvas.requestRenderAll();
      }
      
      // 清除选择状态
      this.selection.selectedElementIds = [];
      this.selection.activeElementId = null;
      this.selection.activeObject = null;
      this.selection.activeObjects = [];
      
      // 发送选择清除事件
      eventBus.emit('element:selection-cleared');
    },
    
    /**
     * 选择所有元素
     */
    selectAllElements() {
      const canvas = this.canvas.fabricCanvas;
      if (!canvas) return;
      
      // 选择所有对象
      const objects = canvas.getObjects();
      if (objects.length === 0) return;
      
      // 创建活动选择
      const activeSelection = new fabric.ActiveSelection(objects, {
        canvas
      });
      
      canvas.setActiveObject(activeSelection);
      canvas.requestRenderAll();
      
      // 更新选择状态
      this.selection.activeObject = activeSelection;
      this.selection.activeObjects = objects;
      this.selection.selectedElementIds = objects
        .map(obj => obj.id as string)
        .filter(Boolean);
      this.selection.activeElementId = this.selection.selectedElementIds[0] || null;
      
      // 发送全选事件
      eventBus.emit('element:all-selected', { count: objects.length });
    },
    
    /**
     * 复制选中元素
     */
    copySelectedElements() {
      const canvas = this.canvas.fabricCanvas;
      if (!canvas || !canvas.getActiveObject()) return;
      
      // 复制选中对象
      canvas.getActiveObject().clone((cloned: fabric.Object) => {
        // 存储到剪贴板
        canvas.clipboard = cloned;
        
        // 发送复制事件
        eventBus.emit('element:copied', { 
          element: canvas.getActiveObject(),
          count: this.selection.activeObjects.length
        });
      });
    },
    
    /**
     * 粘贴元素
     */
    pasteElements() {
      const canvas = this.canvas.fabricCanvas;
      if (!canvas || !canvas.clipboard) return;
      
      // 粘贴对象
      canvas.clipboard.clone((cloned: fabric.Object) => {
        // 调整位置，避免完全重叠
        cloned.set({
          left: (cloned.left || 0) + 10,
          top: (cloned.top || 0) + 10,
          evented: true
        });
        
        // 如果是组合对象，需要处理内部对象
        if (cloned instanceof fabric.Group) {
          cloned.canvas = canvas;
          cloned.forEachObject((obj) => {
            canvas.add(obj);
          });
          
          // 解组后重新组合
          const ungroupedObjects = cloned.getObjects();
          canvas.remove(cloned);
          canvas.add(...ungroupedObjects);
          canvas.setActiveObject(new fabric.ActiveSelection(ungroupedObjects, { canvas }));
        } else {
          canvas.add(cloned);
          canvas.setActiveObject(cloned);
        }
        
        canvas.requestRenderAll();
        
        // 标记项目为已修改
        this.setProjectDirty(true);
        
        // 发送粘贴事件
        eventBus.emit('element:pasted', { element: cloned });
      });
    },
    
    /**
     * 剪切选中元素
     */
    cutSelectedElements() {
      // 先复制，再删除
      this.copySelectedElements();
      this.deleteSelectedElements();
      
      // 发送剪切事件
      eventBus.emit('element:cut', { count: this.selection.activeObjects.length });
    },
    
    /**
     * 删除选中元素
     */
    deleteSelectedElements() {
      const canvas = this.canvas.fabricCanvas;
      if (!canvas) return;
      
      const activeObject = canvas.getActiveObject();
      if (!activeObject) return;
      
      // 删除选中对象
      if (activeObject instanceof fabric.ActiveSelection) {
        // 删除多个对象
        const objects = activeObject.getObjects();
        canvas.discardActiveObject();
        objects.forEach(obj => canvas.remove(obj));
      } else {
        // 删除单个对象
        canvas.remove(activeObject);
      }
      
      canvas.requestRenderAll();
      
      // 清除选择状态
      this.clearSelection();
      
      // 标记项目为已修改
      this.setProjectDirty(true);
      
      // 发送删除事件
      eventBus.emit('element:deleted');
    },
    
    /**
     * 设置多选模式
     * @param isMultiSelect 是否多选
     */
    setMultiSelectMode(isMultiSelect: boolean) {
      this.selection.isMultiSelect = isMultiSelect;
    },
    
    /**
     * 设置编辑模式
     * @param mode 编辑模式
     */
    setEditMode(mode: EditMode) {
      this.editMode = mode;
      
      // 发送模式变更事件
      eventBus.emit('mode:changed', { mode });
    },
    
    /**
     * 设置活动工具
     * @param tool 工具类型
     */
    setActiveTool(tool: ToolType) {
      this.activeTool = tool;
      
      // 根据工具类型设置编辑模式
      switch (tool) {
        case 'select':
          this.setEditMode('select');
          break;
        case 'text':
        case 'shape':
        case 'image':
          this.setEditMode('draw');
          break;
        case 'pen':
          this.setEditMode('draw');
          break;
      }
      
      // 发送工具变更事件
      eventBus.emit('tool:changed', { tool });
    },
    
    /**
     * 设置活动形状类型
     * @param shapeType 形状类型
     */
    setActiveShapeType(shapeType: ShapeType) {
      this.activeShapeType = shapeType;
      
      // 发送形状类型变更事件
      eventBus.emit('shape-type:changed', { shapeType });
    },
    
    /**
     * 切换侧边栏
     */
    toggleSidebar() {
      this.ui.sidebarOpen = !this.ui.sidebarOpen;
    },
    
    /**
     * 设置活动侧边栏标签
     * @param tab 标签类型
     */
    setActiveSidebarTab(tab: SidebarTabType) {
      this.ui.activeSidebarTab = tab;
    },
    
    /**
     * 设置移动视图模式
     * @param isMobile 是否移动视图
     */
    setMobileView(isMobile: boolean) {
      this.ui.isMobileView = isMobile;
      
      // 在移动视图下自动关闭侧边栏
      if (isMobile && this.ui.sidebarOpen) {
        this.ui.sidebarOpen = false;
      }
    },
    
    /**
     * 设置加载状态
     * @param isLoading 是否加载中
     */
    setLoading(isLoading: boolean) {
      this.ui.isLoading = isLoading;
    },
    
    /**
     * 设置项目信息
     * @param id 项目ID
     * @param name 项目名称
     */
    setProject(id: string, name: string) {
      this.project.id = id;
      this.project.name = name;
      this.project.isDirty = false;
      this.project.lastSaved = new Date();
    },
    
    /**
     * 设置项目是否有未保存的更改
     * @param isDirty 是否有未保存的更改
     */
    setProjectDirty(isDirty: boolean) {
      this.project.isDirty = isDirty;
    },
    
    /**
     * 保存项目
     */
    saveProject() {
      // 标记项目为已保存
      this.project.isDirty = false;
      this.project.lastSaved = new Date();
      
      // 发送项目保存事件
      eventBus.emit('project:saved', { 
        id: this.project.id,
        name: this.project.name
      });
    },
    
    /**
     * 清理资源
     */
    cleanup() {
      // 移除事件监听
      const canvas = this.canvas.fabricCanvas;
      if (canvas) {
        canvas.off();
      }
      
      document.removeEventListener('keydown', this.handleKeyDown);
      document.removeEventListener('keyup', this.handleKeyUp);
    }
  }
});